﻿using System;
using System.Linq;
using JBeamLibrary.Types;
using JBeamLibrary.VehicleParts;
using JBeamLibrary.VehicleParts.Elements;
using JBeamLibrary.VehicleParts.Enums;
using Newtonsoft.Json.Linq;

namespace JBeamLibrary.Tools
{
    public static class ObjectExtension
    {
        public static string ToStringOrEmpty(this object obj)
        {
            return obj == null ? string.Empty : obj.ToString();
        }

        public static string ToStringOrDefault(this object obj, string def)
        {
            return obj == null ? def : obj.ToString();
        }

        public static string ToStringOrZero(this object obj)
        {
            var str = obj.ToStringOrEmpty();
            return string.IsNullOrEmpty(str) ? "0" : str;
        }

        public static object ToJBeam(this object obj)
        {
            if (obj is DefaultBoolean)
                return (DefaultBoolean)obj == DefaultBoolean.True;
            if (obj is int && obj.Equals(int.MaxValue))
                return "FLT_MAX";
            if (obj is float && obj.Equals(float.MaxValue))
                return "FLT_MAX";
            if (obj is long && obj.Equals(long.MaxValue))
                return "FLT_MAX";
            if (obj is double && obj.Equals(double.MaxValue))
                return "FLT_MAX";
            if (obj is short && obj.Equals(short.MaxValue))
                return "FLT_MAX";
            if (obj is NodeMaterial)
                return NodeMaterials.GetStringValue((NodeMaterial)obj);
            if (obj is BeamType)
                return BeamTypes.GetStringValue((BeamType)obj);
            if (obj is Float3)
                return new JObject(
                    new JProperty("x", ((Float3)obj).X.ToJBeam()),
                    new JProperty("y", ((Float3)obj).Y.ToJBeam()),
                    new JProperty("z", ((Float3)obj).Z.ToJBeam()));
            if (obj is Color)
                return new JObject(
                    new JProperty("a", ((Color)obj).A.ToJBeam()),
                    new JProperty("r", ((Color)obj).R.ToJBeam()),
                    new JProperty("g", ((Color)obj).G.ToJBeam()),
                    new JProperty("b", ((Color)obj).B.ToJBeam()));
            if (obj is AxleBeams)
                return new JArray(((AxleBeams)obj).ToArray<object>());
            return obj ?? string.Empty;
        }

        public static bool SafeEquals(this object obj, object other)
        {
            return
                (obj == null && other == null) ||
                (obj != null && obj.Equals(other));
        }

        public static bool IsEmpty(this object obj)
        {
            return obj == null || obj.SafeEquals(string.Empty) || obj == DBNull.Value;
        }

        public static T To<T>(this object obj)
        {
            if (obj is T) return (T)obj;
            if (obj.IsEmpty()) return default(T);
            return (T)Convert.ChangeType(obj, typeof(T));
        }
    }
}
